package com._9xcloud.leaverequest.web.util;

import com._9xcloud.leaverequest.domain.User;
import org.springframework.security.crypto.codec.Hex;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;


public class TokenUtils {

    public static final String MAGIC_KEY = "obfuscate";
    public static final String TOKEN_DELIMITER = ":";

    public static String createToken(User user, int expireHours) {
        /* Expires in one hour */
        long expires = System.currentTimeMillis() + 1000L * 60 * 60 * expireHours;

        StringBuilder tokenBuilder = new StringBuilder();
        tokenBuilder.append(user.getUserRole().getAuthority());
        tokenBuilder.append(TOKEN_DELIMITER);
        tokenBuilder.append(user.getUsername());
        tokenBuilder.append(TOKEN_DELIMITER);
        tokenBuilder.append(expires);
        tokenBuilder.append(TOKEN_DELIMITER);
        tokenBuilder.append(TokenUtils.computeSignature(user, expires));

        return tokenBuilder.toString();
    }


    public static String computeSignature(User user, long expires) {
        StringBuilder signatureBuilder = new StringBuilder();
        signatureBuilder.append(user.getUserRole().getAuthority());
        signatureBuilder.append(TOKEN_DELIMITER);
        signatureBuilder.append(user.getUsername());
        signatureBuilder.append(TOKEN_DELIMITER);
        signatureBuilder.append(expires);
        signatureBuilder.append(TOKEN_DELIMITER);
        signatureBuilder.append(user.getPassword());
        signatureBuilder.append(TOKEN_DELIMITER);
        signatureBuilder.append(TokenUtils.MAGIC_KEY);

        MessageDigest digest;
        try {
            digest = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalStateException("No MD5 algorithm available!");
        }

        return new String(Hex.encode(digest.digest(signatureBuilder.toString().getBytes())));
    }


    public static String getRoleNameFromToken(String authToken) {
        if (null == authToken) {
            return null;
        }

        String[] parts = authToken.split(TOKEN_DELIMITER);
        return parts[0];
    }

    public static String getUserNameFromToken(String authToken) {
        if (null == authToken) {
            return null;
        }

        String[] parts = authToken.split(TOKEN_DELIMITER);
        return parts[1];
    }


    public static boolean validateToken(String authToken, User user) {
        String[] parts = authToken.split(TOKEN_DELIMITER);
        long expires = Long.parseLong(parts[2]);
        String signature = parts[3];

        if (expires < System.currentTimeMillis()) {
            return false;
        }

        return signature.equals(TokenUtils.computeSignature(user, expires));
    }
}